-- LuaTools需要PROJECT和VERSION这两个信息
PROJECT = "esp32s3-micro-filter"
VERSION = "1.0.0"

-- 引入必要的库文件(lua编写), 内部库不需要require
sys = require("sys")
require("sysplus")



--添加硬狗防止程序卡死
if wdt then
    wdt.init(9000)--初始化watchdog设置为9s
    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
end


--引脚定义
--  步进电机
stepPin = 17 --step
dirPin = 16 --方向
enPin = 15   --启停
-- 水位传感器
waterLevelPin = 14
-- 水泵
waterPumpPin = 18
-- uart串口ID
uartId = 2

-- 默认配置
initConfig = {
    washCdTime = 10, --延时时间 10-60 秒
    runMode= 1, --运行模式 1自动2定时
    drumSpeed = 50,--转桶速度 1-100 %
    timerGap = 30, --定时间隔 /分钟
}

runModeTxt = {[1]="自动",[2]="定时"}
-- 冲洗记录
washTime = 0 --冲洗时长
washCount = 0 --冲洗次数


-- 步进电机初始化
gpio.setup(enPin, 0)
pwm.open(stepPin, 100+initConfig.drumSpeed*5, 80)
gpio.setup(dirPin, 1)
--水位传感器引脚 输入模式
gpio.setup(waterLevelPin, nil, gpio.PULLUP)

gpio.setup(waterPumpPin,1)
-- 数据库初始化
if fskv.init() then
    log.info("fdb", "kv数据库初始化成功")
end
washConfig = fskv.get('wash-config')
if washConfig then
    print("历史数据获取成功")
    print("==当前运行配置==")
    print(" runMode = ",washConfig.runMode)
    print(" washCdTime = ",washConfig.washCdTime)
    print(" drumSpeed = ",washConfig.drumSpeed)
    print(" timerGap = ",washConfig.timerGap)
else
    print('初始化配置')
    -- 初次初始化直接set存表  下次修改数据使用fskv.sett(key, skey, value)
    fskv.set('wash-config',initConfig)
end



--反冲洗任务
sys.taskInit(function ()
    while true do

        if washTime>0 then
            print("反冲洗开启")
            gpio.set(enPin, 0)
            gpio.set(waterPumpPin, 1)
            washTime = washTime-1
        else
            print("反冲洗关闭")
            gpio.set(enPin, 1)
            gpio.set(waterPumpPin, 0)
            washTime = 0
        end
        sys.wait(1000)
    end
end)




-- 水位检测任务 （忽略模式 任何模式下水位异常都开启反冲洗）
sys.taskInit(function()
    -- local press_start_time = 0
    -- local press_start_status = false
    while true do
        if gpio.get(waterLevelPin) == 1 then -- 按下
            print("水位高度异常")
            washTime = washConfig.washCdTime
        end
        sys.wait(50)
    end
end)


-- 定时任务函数
function timer_func(state)
    log.info("==定时时间到==",washConfig.timerGap, state)
    washTime = washConfig.washCdTime
end


-- 定时器
sys.taskInit(function()
    timerId = nil
    if  washConfig.runMode == 2 then
        timerId = sys.timerLoopStart(timer_func,washConfig.timerGap*60*1000)
        log.info("定时器启动", timerId)
    end
    -- 订阅定时器变更操作 （模式变更 or 时长变更）
    sys.subscribe("TIMER_CHANGE", function(state)
        log.info("sys", "定时器时间变更", state)
        if timerId then
            sys.timerStop(timerId)
            log.info("定时器停止", timerId)
        end
        -- 启动新的定时器
        timerId = sys.timerLoopStart(timer_func,washConfig.timerGap*60*1000)
        log.info("定时器启动", timerId)
    end)

end)


-- 定义startsWith函数
local function starts_with(str, prefix)
    return #str >= #prefix and str:sub(1, #prefix) == prefix
end
-- 字符串转数组
function split(str, delimiter)
    local result = {}
    for match in string.gmatch(str, "([^"..delimiter.."]+)") do
        table.insert(result, match)
    end
    return result
end

-- 处理屏幕数据 并存入数据库
local function handelScreenData(data)
    local arrData = split(data, "-")
    local valValue = tonumber(arrData[2])
    washConfig[arrData[1]] = valValue
    print("==存储数据==",arrData[1],valValue)
    fskv.sett('wash-config',arrData[1],valValue)
    -- 模式更改或定时间隔变更
    if arrData[1]=='timerGap' or arrData[1]=='runMode' then
        sys.publish("TIMER_CHANGE", 'timergap or runmode change')
    end
    if arrData[1]=='drumSpeed' then
        pwm.open(stepPin, 100+ initConfig.drumSpeed*5,80)
    end
end

-- 串口初始化及监听
sys.taskInit(function()
    sys.wait(3000)--延时3s等待屏幕启动稳定
    -- 初始化串口
    uart.setup(uartId, 9600, 8, 1, uart.NONE)
    -- 发送初始状态数据
    data1 = "page0.t5.txt=\""..runModeTxt[washConfig.runMode].."\"" .. string.char(0xff,0xff,0xff)
    uart.write(uartId, data1)
    data2 = "page0.t6.txt=\""..washConfig.washCdTime.."\"" .. string.char(0xff,0xff,0xff)
    uart.write(uartId, data2)
    data3 = "page0.t7.txt=\""..washConfig.drumSpeed.."\"" .. string.char(0xff,0xff,0xff)
    uart.write(uartId, data3)
    data4 = "page0.t9.txt=\""..washConfig.timerGap.."\"" .. string.char(0xff,0xff,0xff)
    uart.write(uartId, data4)

    -- 监听串口接收事件
    uart.on(uartId, "receive", function(id, len)
        local newData = uart.read(id, len)
        -- print("串口接收：", newData)
        print("新数据", newData)

        if starts_with(newData, "runMode") or starts_with(newData, "washCdTime") or starts_with(newData, "drumSpeed") or starts_with(newData, "timerGap") then
            -- 处理配置数据逻辑
            handelScreenData(newData)
        end
    end)
end)


-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!
